package controller

import (
	"context"
	"fmt"
	"gg_server/db"
	"gg_server/model"
	"gg_server/response"
	"gg_server/util"
	"gg_server/websocket"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

// 好友

type Friend struct{}

var FriendController *Friend

func init() {
	FriendController = &Friend{}
}

// 添加好友
func (f *Friend) Add(ctx *gin.Context) {
	friend_id, b := ctx.GetQuery("friend_id")
	// 判断是否传入 friend_id
	if !b {
		response.GetError().ParameterError("参数不完整")
		return
	}
	f_id, err := strconv.Atoi(friend_id)
	if err != nil {
		response.GetError().ParameterError("参数有问题")
		return
	}

	add_information := ctx.Query("add_information")
	note := ctx.Query("note")

	// 获取用户id
	user_id := ctx.GetInt("id")

	// 判断是否是自己
	if f_id == user_id {
		response.GetError().ParameterError("不能添加自己为好友哦")
		return
	}

	// 判断是否已经添加过该好友
	var friend_request_list []model.FriendRequest
	db.CreateSQLDB().Where("user_id = ? AND friend_id = ? AND status = ?", user_id, f_id, 1).Find(&friend_request_list)
	if len(friend_request_list) > 0 {
		// 存在添加信息
		response.GetError().ParameterError("已经添加过该用户,不能重复添加")
		return
	}

	// 创建 好友请求
	friend_request := model.FriendRequest{
		UserId:         user_id,
		FriendId:       f_id,
		Status:         1,
		AddInformation: add_information,
		Note:           note,
		CreateTime:     time.Now(),
	}

	// 插入好友请求
	result := db.CreateSQLDB().Create(&friend_request)
	if result.Error != nil {
		response.GetError().ParameterError("未能找到该好友")
		return
	}

	// 通过websocket提示用户 被请求添加好友
	go func() {
		// 重新查找好友请求表
		fr := model.FriendRequest{
			Id: friend_request.Id,
		}

		db.CreateSQLDB().Preload("User").Preload("Friend").Find(&fr)

		wfr := websocket.FriendRequest{
			Request: fr,
		}

		wfr.Handle(f_id)
	}()

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "好友请求发送成功",
		Data: gin.H{},
	})
}

// 查找通过账号用户
func (f *Friend) FindUserByAccount(ctx *gin.Context) {
	accountString, b := ctx.GetQuery("account")
	if !b {
		response.GetError().ParameterError("参数不完整")
		return
	}
	account, err := strconv.Atoi(accountString)
	if err != nil {
		response.GetError().ParameterError("参数有问题")
		return
	}

	// 创建用户对象
	var user model.User

	// 查找用户
	result := db.CreateSQLDB().Where("account = ?", account).Find(&user)
	if result.RowsAffected <= 0 {
		response.GetError().ParameterError("没有找到该用户")
		return
	}

	// 储存是否为好友  0 不是好友  1 是好友 2 本人
	isFriend := 0
	id := ctx.GetInt("id")
	if id == user.Id {
		isFriend = 2
	} else {
		// 查询好友表 判断是否为好友
		result = db.CreateSQLDB().Where("user_id = ? AND friend_id = ?", id, user.Id).Find(&model.Friend{})
		if result.RowsAffected <= 0 {
			isFriend = 0
		} else {
			isFriend = 1
		}
	}

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "成功找到该用户",
		Data: gin.H{
			"user":     user,
			"isFriend": isFriend,
		},
	})
}

// 查找用户 通过id
func (f *Friend) FindUserById(ctx *gin.Context) {
	idString, b := ctx.GetQuery("id")
	if !b {
		response.GetError().ParameterError("参数不完整")
		return
	}
	id, err := strconv.Atoi(idString)
	if err != nil {
		response.GetError().ParameterError("参数有问题")
		return
	}

	user := model.User{
		Id: id,
	}

	result := db.CreateSQLDB().Find(&user)
	if result.RowsAffected <= 0 {
		response.GetError().ParameterError("没有找到该用户")
		return
	}

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "查找成功",
		Data: gin.H{
			"user": user,
		},
	})
}

// 获取好友请求列表
func (f *Friend) FriendRequestList(ctx *gin.Context) {
	// 列表的类型 0好友请求，1 好友添加
	listTypeTemp := ctx.DefaultQuery("type", "0")
	listType, err := strconv.Atoi(listTypeTemp)
	if err != nil {
		response.GetError().ParameterError("参数有问题")
		return
	}

	user_id := ctx.GetInt("id")

	var friendRequestList []model.FriendRequest

	if listType == 0 {
		db.CreateSQLDB().Where(&model.FriendRequest{UserId: user_id}).Preload("User").Preload("Friend").Find(&friendRequestList)
	} else {
		db.CreateSQLDB().Where(&model.FriendRequest{FriendId: user_id}).Preload("User").Preload("Friend").Find(&friendRequestList)
	}

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "查询成功",
		Data: gin.H{
			"friendRequestList": friendRequestList,
		},
	})
}

// 同意好友请求  接收客户端数据
type agreeFriend struct {
	// 好友请求表 id
	Id int `json:"id" binding:"required"`
	// 我的备注
	Note string `json:"note" binding:"required"`
	// 处理状态 2同意，3不同意
	Status int `json:"status" binding:"required"`
}

// 同意好友请求
func (f *Friend) AgreeFriendRequest(ctx *gin.Context) {
	var agreeInfo agreeFriend
	err := ctx.ShouldBind(&agreeInfo)
	if err != nil {
		response.GetError().ParameterError("参数不完整")
	}

	friendRequest := model.FriendRequest{
		Id: agreeInfo.Id,
	}
	// 查找好友请求表
	result := db.CreateSQLDB().Where("status = ?", 1).Find(&friendRequest)
	if result.RowsAffected <= 0 {
		response.GetError().ParameterError("好友请求已失效")
	}

	// 更新请求表状态
	friendRequest.Status = agreeInfo.Status
	result = db.CreateSQLDB().Updates(friendRequest)
	if result.Error != nil || result.RowsAffected <= 0 {
		response.GetError().ServerError("好友请求失败")
	}
	// 判断是否同意了好友请求
	if agreeInfo.Status == 3 {
		// 拒绝了 直接退出
		response.SendSuccessMsg(ctx, &response.SuccessMsg{
			Code: 200,
			Msg:  "已拒绝该用户的好友请求",
		})
		return
	}

	// 创建聊天 集合
	chatCollection := model.Chat{
		Users: []int{friendRequest.UserId, friendRequest.FriendId},
		Chat:  []model.ChatMsg{},
	}
	mongoRes, err := db.CreateMongoDB().Collection("chat").InsertOne(context.TODO(), chatCollection)
	if err != nil {
		response.GetError().ServerError(fmt.Sprint("创建聊天失败, err:", err))
	}

	// 获取当前时间
	create_time := time.Now()

	// 创建好友表
	userFriend := model.Friend{
		UserId:     friendRequest.UserId,
		FriendId:   friendRequest.FriendId,
		Note:       friendRequest.Note,
		Chat_id:    mongoRes.InsertedID.(primitive.ObjectID).Hex(),
		CreateTime: create_time,
	}
	userFriend02 := model.Friend{
		UserId:     friendRequest.FriendId,
		FriendId:   friendRequest.UserId,
		Note:       agreeInfo.Note,
		Chat_id:    mongoRes.InsertedID.(primitive.ObjectID).Hex(),
		CreateTime: create_time,
	}

	result = db.CreateSQLDB().Save(&userFriend)
	if result.Error != nil || result.RowsAffected <= 0 {
		response.GetError().ServerError("添加好友失败,原因:创建好友失败")
	}
	result = db.CreateSQLDB().Save(&userFriend02)
	if result.Error != nil || result.RowsAffected <= 0 {
		response.GetError().ServerError("添加好友失败,原因:创建好友失败")
	}

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "添加好友成功",
	})
}

// 获取好友列表
func (f *Friend) GetFriendList(ctx *gin.Context) {
	// 获取用户id
	id := ctx.GetInt("id")

	// 好友列表
	var friendList []model.Friend
	result := db.CreateSQLDB().Where("user_id = ?", id).Preload("Friend").Find(&friendList)
	if result.Error != nil {
		response.GetError().ServerError("出现了错误:err" + result.Error.Error())
		return
	}

	// 向 客户端 的返回数据 格式
	type SendList struct {
		// 好友的信息
		Friend model.Friend `json:"friend"`
		// 最新的消息
		Chat model.ChatMsg `json:"chat"`
		// 未读的信息数
		Unread int `json:"unread"`
	}

	var list []SendList = make([]SendList, 0)

	for _, _friend := range friendList {
		_id, _ := primitive.ObjectIDFromHex(_friend.Chat_id)

		// 查找文章
		chart := util.MongoD.GetChat(bson.D{{Key: "_id", Value: _id}})

		var unread int = 0
		// 计算出未读的数据
		// 限制 100条  超过99条 按 99条算
		for i := len(chart.Chat) - 1; i >= len(chart.Chat)-100 && i >= 0; i-- {
			if chart.Chat[i].Read || id == chart.Chat[i].Id {
				// id等于当前用户的id也不计算
				// true已读，不计数
				continue
			}
			unread++
		}

		// 防止数组越界
		var c model.ChatMsg
		if len(chart.Chat) <= 0 {
			c = model.ChatMsg{}
		}else{
			c = chart.Chat[len(chart.Chat)-1]
		}

		list = append(list, SendList{
			Friend: _friend,
			Chat:   c,
			Unread: unread,
		})
	}

	// 查找成功
	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "查询成功",
		Data: gin.H{
			"friendList": list,
		},
	})
}

// 获取与好友的聊天记录
func (f *Friend) GetChat(ctx *gin.Context) {
	// 获取用户id
	user_id := ctx.GetInt("id")

	// // 分页 的 大小  默认10
	// pageSizeString := ctx.DefaultQuery("pageSize", "10")
	// pageSize, err := strconv.Atoi(pageSizeString)
	// if err != nil {
	// 	response.GetError().ParameterError("参数类型出现问题")
	// 	return
	// }

	// // 分页 的 页数  默认1
	// pageString := ctx.DefaultQuery("page", "1")
	// page, err := strconv.Atoi(pageString)
	// if err != nil {
	// 	response.GetError().ParameterError("参数类型出现问题")
	// 	return
	// }

	// 好友id
	friend_idString, b := ctx.GetQuery("id")
	if !b {
		response.GetError().ParameterError("参数不完整")
		return
	}
	friend_id, err := strconv.Atoi(friend_idString)
	if err != nil {
		response.GetError().ParameterError("参数类型出现问题")
		return
	}

	// 拿到好友列表
	var friend model.Friend
	result := db.CreateSQLDB().Where("user_id = ? AND friend_id = ?", user_id, friend_id).Find(&friend)
	if result.RowsAffected <= 0 {
		response.GetError().ParameterError("没有找到该好友")
	}

	_id, _ := primitive.ObjectIDFromHex(friend.Chat_id)
	// 查找聊天记录 并将对方 发送的消息设置为已读
	var chat model.Chat
	util.MongoD.FindOnUpdateChatRead(_id, friend_id, &chat)

	// 聊天信息分页
	// pageTotal := chat.PageHandle(page, pageSize)

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "查询成功",
		Data: gin.H{
			"chat":      chat,
		},
	})
}

// 删除好友
func (f *Friend) DeleteFriend(ctx *gin.Context) {
	// 获取当前用户的id
	user_id := ctx.GetInt("id")

	// 获取 要删除的好友id
	friend_id, b := ctx.GetPostForm("friend_id")
	if !b {
		response.GetError().ParameterError("参数不完整")
		return
	}

	// 删除好友
	result := db.CreateSQLDB().Where("user_id = ? AND friend_id = ?", user_id, friend_id).Delete(&model.Friend{})
	if result.Error != nil || result.RowsAffected <= 0 {
		response.GetError().ServerError("删除好友失败")
		return
	}

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "删除好友成功",
		Data: gin.H{},
	})
}
